﻿using System;
using System.Drawing;
// using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace MobileTDL
{
    public class ToDoTask : ToDoTaskContainer, ICloneable<ToDoTask>
    {
        public ToDoTask()
        {
        }

        public ToDoTask(XmlDocument doc, XmlElement element)
            : base(doc, element)
        {
        }

        public string AllocatedBy
        {
            get { return GetAttribute("ALLOCATEDBY").Value; }
            set { GetAttribute("ALLOCATEDBY").Value = value; }
        }

        public string CalcPercentageDone
        {
            get { return GetAttribute("CALCPERCENTDONE").Value; }
            set { GetAttribute("CALCPERCENTDONE").Value = value; }
        }

        public string CalcTimeSpent
        {
            get { return GetAttribute("CALCTIMESPENT").Value; }
            set { GetAttribute("CALCTIMESPENT").Value = value; }
        }

        public string Category
        {
            get { return GetAttribute("CATEGORY").Value; }
            set { GetAttribute("CATEGORY").Value = value; }
        }

        public string Comments
        {
            get { return GetAttribute("COMMENTS").Value; }
            set { GetAttribute("COMMENTS").Value = value; }
        }

        /// <summary>
        /// Completion indicator. True when completion percentage reaches 100%.
        /// This is a calculated field.
        /// </summary>
        public bool Completed
        {
            get { return (PercentDone == 100); }
        }

        public bool ContainsCompleted
        {
            get
            {
                bool containsCompleted = Completed;
                if (!containsCompleted)
                {
                    foreach (ToDoTask subTask in Items)
                    {
                        if (subTask.ContainsCompleted)
                        {
                            containsCompleted = true;
                            break;
                        }
                    }
                }
                return containsCompleted;
            }
        }

        public bool ContainsIncompleted
        {
            get
            {
                bool containsIncompleted = !Completed;
                if (!containsIncompleted)
                {
                    foreach (ToDoTask subTask in Items)
                    {
                        if (subTask.ContainsIncompleted)
                        {
                            containsIncompleted = true;
                            break;
                        }
                    }
                }
                return containsIncompleted;
            }
        }

        public DateTime? CreationDate
        {
            get { return ParseOADate(GetAttribute("CREATIONDATE").Value); }
            set
            {
                GetAttribute("CREATIONDATE").Value = (value.HasValue ? value.Value.ToOADate().ToString() : "");
                CreationDateString = (value.HasValue ? value.Value.ToString() : "");
            }
        }

        private string CreationDateString
        {
            get { return GetAttribute("CREATIONDATESTRING").Value; }
            set { GetAttribute("CREATIONDATESTRING").Value = value; }
        }

        public string CustomComments
        {
            get { return GetAttribute("CUSTOMCOMMENTS").Value; }
            set { GetAttribute("CUSTOMCOMMENTS").Value = value; }
        }

        public string Depends
        {
            get { return GetAttribute("DEPENDS").Value; }
            set { GetAttribute("DEPENDS").Value = value; }
        }

        public DateTime? DoneDate
        {
            get { return ParseOADate(GetAttribute("DONEDATE").Value); }
            set
            {
                GetAttribute("DONEDATE").Value = (value.HasValue ? value.Value.ToOADate().ToString() : "");
                DoneDateString = (value.HasValue ? value.Value.ToString() : "");
            }
        }

        private string DoneDateString
        {
            get { return GetAttribute("DONEDATESTRING").Value; }
            set { GetAttribute("DONEDATESTRING").Value = value; }
        }

        public DateTime? DueDate
        {
            get { return ParseOADate(GetAttribute("DUEDATE").Value); }
            set
            {
                GetAttribute("DUEDATE").Value = (value.HasValue ? value.Value.ToOADate().ToString() : "");
                DueDateString = (value.HasValue ? value.Value.ToString() : "");
            }
        }

        private string DueDateString
        {
            get { return GetAttribute("DUEDATESTRING").Value; }
            set { GetAttribute("DUEDATESTRING").Value = value; }
        }

        public DateTime? EarliestDueDate
        {
            get { return ParseOADate(GetAttribute("EARLIESTDUEDATE").Value); }
            set { GetAttribute("EARLIESTDUEDATE").Value = (value.HasValue ? value.Value.ToOADate().ToString() : ""); }
        }

        public string ExternalId
        {
            get { return GetAttribute("EXTERNALID").Value; }
            set { GetAttribute("EXTERNALID").Value = value; }
        }

        public string FileRefPath
        {
            get { return GetAttribute("FILEREFPATH").Value; }
            set { GetAttribute("FILEREFPATH").Value = value; }
        }

        public int? HighestPriority
        {
            get { return ParseInt32(HighestPriorityString); }
            set { HighestPriorityString = value.ToString(); }
        }

        private string HighestPriorityString
        {
            get { return GetAttribute("HIGHESTPRIORITY").Value; }
            set { GetAttribute("HIGHESTPRIORITY").Value = value; }
        }

        public string Id
        {
            get { return GetAttribute("ID").Value; }
            set { GetAttribute("ID").Value = value; }
        }

        public DateTime? LastModified
        {
            get { return ParseOADate(GetAttribute("LASTMOD").Value); }
            set
            {
                GetAttribute("LASTMOD").Value = (value.HasValue ? value.Value.ToOADate().ToString() : "");
                LastModifiedString = (value.HasValue ? value.Value.ToString() : "");
            }
        }

        private string LastModifiedString
        {
            get { return GetAttribute("LASTMODSTRING").Value; }
            set { GetAttribute("LASTMODSTRING").Value = value; }
        }

        public string NumberCategory
        {
            get { return GetAttribute("NUMCATEGORY").Value; }
            set { GetAttribute("NUMCATEGORY").Value = value; }
        }

        public int? PercentDone
        {
            get { return ParseInt32(GetAttribute("PERCENTDONE").Value); }
            set { GetAttribute("PERCENTDONE").Value = (value.HasValue ? value.Value.ToString() : ""); }
        }

        public string Person
        {
            get { return GetAttribute("PERSON").Value; }
            set { GetAttribute("PERSON").Value = value; }
        }

        public int? Position
        {
            get { return ParseInt32(PositionString); }
            set { PositionString = (value.HasValue ? value.Value.ToString() : ""); }
        }

        private string PositionString
        {
            get { return GetAttribute("POS").Value; }
            set { GetAttribute("POS").Value = value; }
        }

        public int? Priority
        {
            get { return ParseInt32(PriorityString); }
            set { PriorityString = (value.HasValue ? value.Value.ToString() : ""); }
        }

        private string PriorityString
        {
            get { return GetAttribute("PRIORITY").Value; }
            set { GetAttribute("PRIORITY").Value = value; }
        }

        public Color PriorityColor
        {
            get
            {
                Color color;
                int weightedPriority = (100 / (HighestPriority.HasValue ? HighestPriority.Value : 10)) * (Priority.HasValue ? Priority.Value : 5);
                if (weightedPriority >= 80) color = Color.Red;
                else if (weightedPriority >= 60) color = Color.Purple;
                else if (weightedPriority >= 40) color = Color.Blue;
                else if (weightedPriority >= 20) color = Color.PaleTurquoise;
                else color = Color.Green;
                return color;
            }
        }

        public string PriorityColorString
        {
            get { return GetAttribute("PRIORITYCOLOR").Value; }
            set { GetAttribute("PRIORITYCOLOR").Value = value; }
        }

        public string PriorityWebColorString
        {
            get { return GetAttribute("PRIORITYWEBCOLOR").Value; }
            set { GetAttribute("PRIORITYWEBCOLOR").Value = value; }
        }

        public string Risk
        {
            get { return GetAttribute("RISK").Value; }
            set { GetAttribute("RISK").Value = value; }
        }

        public DateTime? StartDate
        {
            get { return ParseOADate(GetAttribute("STARTDATE").Value); }
            set
            {
                GetAttribute("STARTDATE").Value = (value.HasValue ? value.Value.ToOADate().ToString() : "");
                StartDateString = (value.HasValue ? value.Value.ToString() : "");
            }
        }

        private string StartDateString
        {
            get { return GetAttribute("STARTDATESTRING").Value; }
            set { GetAttribute("STARTDATESTRING").Value = value; }
        }

        public string Status
        {
            get { return GetAttribute("STATUS").Value; }
            set { GetAttribute("STATUS").Value = value; }
        }

        public string TextColor
        {
            get { return GetAttribute("TEXTCOLOR").Value; }
            set { GetAttribute("TEXTCOLOR").Value = value; }
        }

        public string TextWebColor
        {
            get { return GetAttribute("TEXTWEBCOLOR").Value; }
            set { GetAttribute("TEXTWEBCOLOR").Value = value; }
        }

        public string TimeEstimate
        {
            get { return GetAttribute("TIMEESTIMATE").Value; }
            set { GetAttribute("TIMEESTIMATE").Value = value; }
        }

        public string TimeEstimateUnits
        {
            get { return GetAttribute("TIMEESTUNITS").Value; }
            set { GetAttribute("TIMEESTUNITS").Value = value; }
        }

        public string TimeSpent
        {
            get { return GetAttribute("TIMESPENT").Value; }
            set { GetAttribute("TIMESPENT").Value = value; }
        }

        public string TimeSpentUnits
        {
            get { return GetAttribute("TIMESPENTUNITS").Value; }
            set { GetAttribute("TIMESPENTUNITS").Value = value; }
        }

        public string Title
        {
            get { return GetAttribute("TITLE").Value; }
            set { GetAttribute("TITLE").Value = value; }
        }


        public ToDoTask Clone()
        {
            return Clone(false);
        }

        public ToDoTask Clone(bool deepCopy)
        {
            ToDoTask task = CreateTask();
            task.CreationDate = CreationDate;
            task.CreationDateString = CreationDateString;
            task.HighestPriorityString = HighestPriorityString;
            task.Id = Id;
            task.LastModified = LastModified;
            task.LastModifiedString = LastModifiedString;
            task.PercentDone = PercentDone;
            task.PositionString = PositionString;
            task.PriorityString = PriorityString;
            task.PriorityColorString = PriorityColorString;
            task.PriorityWebColorString = PriorityWebColorString;
            task.Risk = Risk;
            task.StartDate = StartDate;
            task.StartDateString = StartDateString;
            task.Title = Title;

            foreach (ToDoTask subTask in Items)
            {
                if (deepCopy) task.Items.Add(subTask.Clone(deepCopy));
                else task.Items.Add(subTask);
            }

            return task;
        }

        public void SetComplete()
        {
            PercentDone = 100;
            DoneDate = DateTime.Now;
        }

        public void SetUncomplete(int percentage)
        {
            PercentDone = percentage;
            DoneDateString = null;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Created=" + CreationDateString);
            sb.Append(", last modified=" + LastModifiedString);
            sb.Append(", id=" + Id);
            sb.Append(", priority=" + PriorityString);
            sb.Append(", % complete=" + PercentDone);
            sb.Append(", risk=" + Risk);
            sb.Append(", start date=" + StartDateString);
            sb.Append(", title=" + Title);
            return sb.ToString();
        }
    }
}
